package tests.ui;

import java.awt.Color;
import java.lang.reflect.Field;
import java.util.List;
import java.util.ArrayList;

import junit.framework.Assert;
import junit.framework.TestCase;
import laboratoryQ.experiment.ui.UIUtils;
import laboratoryQ.ui.draw.style.*;
import laboratoryQ.ui.draw.IDrawer;
import laboratoryQ.ui.draw.MultiDrawer;
import laboratoryQ.flatness.DiagramData;
import laboratoryQ.flatness.ui.DrawDiagramOnComponent;

import javax.swing.*;

public class TestDrawers extends TestCase {
	public void testDrawDiagramOnComponent() {
		DrawDiagramOnComponent diaOnComp = new DrawDiagramOnComponent();
		List<DiagramData> diaList = new ArrayList<DiagramData>();
		diaList.add(newDiagramData2());
		diaList.add(newDiagramData3());
		JComponent comp = diaOnComp.dia2component(
				diaList,
				"X",
				"Y"
		);
		IDrawer drawer = getDrawer(comp);
		tests.fakes.StoreLineDrawsGraphic g = new tests.fakes.StoreLineDrawsGraphic();
		ChainStylizerStylizer stylizer = new ChainStylizerStylizer();
		stylizer.addStage(new PaintDiaItem(new Color[] { Color.RED, Color.GREEN }));

		drawer.draw(g, stylizer);
		Assert.assertEquals(
				"setcolor{java.awt.Color[r=255,g=0,b=0]}line{26,150,28,25}setcolor{java.awt.Color[r=0,g=255,b=0]}line{236,137,255,125}line{255,125,275,112}setcolor{java.awt.Color[r=0,g=0,b=0]}line{20,275,30,275}drawString{0,-75,277}line{20,212,30,212}drawString{5,-75,215}line{20,150,30,150}drawString{10,-75,152}line{20,87,30,87}drawString{15,-75,90}line{25,270,25,280}drawString{0,0,290}line{63,270,63,280}drawString{20,38,290}line{101,270,101,280}drawString{40,76,290}line{140,270,140,280}drawString{60,115,290}line{178,270,178,280}drawString{80,153,290}line{217,270,217,280}drawString{100,192,290}line{25,275,275,275}line{275,275,266,280}line{275,275,266,270}drawString{X,250,290}line{25,275,25,25}line{25,25,30,33}line{25,25,20,33}drawString{Y,75,30}",
				g.getCalls()
		);

		g = new tests.fakes.StoreLineDrawsGraphic();
		diaList.clear();
		diaList.add(newDiagramData2());
		diaList.add(newDiagramData3());
		stylizer = new ChainStylizerStylizer();
		stylizer.addStage(new PaintDiaItem(new Color[] { Color.GREEN, Color.BLUE }));
		comp = diaOnComp.dia2component(
				diaList,
				"X",
				"Y"
		);
		drawer = getDrawer(comp);
		
		drawer.draw(g, stylizer);
		Assert.assertEquals(
				"setcolor{java.awt.Color[r=0,g=255,b=0]}line{26,150,28,25}setcolor{java.awt.Color[r=0,g=0,b=255]}line{236,137,255,125}line{255,125,275,112}setcolor{java.awt.Color[r=0,g=0,b=0]}line{20,275,30,275}drawString{0,-75,277}line{20,212,30,212}drawString{5,-75,215}line{20,150,30,150}drawString{10,-75,152}line{20,87,30,87}drawString{15,-75,90}line{25,270,25,280}drawString{0,0,290}line{63,270,63,280}drawString{20,38,290}line{101,270,101,280}drawString{40,76,290}line{140,270,140,280}drawString{60,115,290}line{178,270,178,280}drawString{80,153,290}line{217,270,217,280}drawString{100,192,290}line{25,275,275,275}line{275,275,266,280}line{275,275,266,270}drawString{X,250,290}line{25,275,25,25}line{25,25,30,33}line{25,25,20,33}drawString{Y,75,30}",
				g.getCalls()
		);
	}

	public void testStylizer() {
		IStylizer stylizer = new IStylizer() {
			@Override
			public void fillStyle(IStyle style) {
				for (IStyleProperty p : style.listPropertices()) {
					if (p instanceof ColorProperty) {
						p.setValue(Color.RED);
					}
				}
			}
		};
		IStyle style = new Style();
		IStyleProperty colorProperty = new ColorProperty(); 
		IStyleProperty intProperty = new BaseStypeProperty(123);
		style.listPropertices().add(colorProperty);
		style.listPropertices().add(intProperty);
		stylizer.fillStyle(style);
		Color color = (Color) colorProperty.getValue();
		Assert.assertEquals(Color.RED, color);
		Assert.assertEquals(123, intProperty.getValue());
	}
	
	public void testDiagramItemColorStyle() {
		IStyle style = new Style();
		IStyleProperty diaItColorProperty0 = new DiagramItemColorProperty(0);
		IStyleProperty diaItColorProperty1 = new DiagramItemColorProperty(1);
		IStyleProperty diaItColorProperty2 = new DiagramItemColorProperty(2);
		style.listPropertices().add(diaItColorProperty0);
		style.listPropertices().add(diaItColorProperty1);
		style.listPropertices().add(diaItColorProperty2);
		
		IStylizer stylizer = UIUtils.configureDefaultUIStylizer();
		stylizer.fillStyle(style);
		
		Assert.assertEquals(UIUtils.COLORS_COLLECTION[0], diaItColorProperty0.getValue());
		Assert.assertEquals(UIUtils.COLORS_COLLECTION[1], diaItColorProperty1.getValue());
		Assert.assertEquals(UIUtils.COLORS_COLLECTION[2], diaItColorProperty2.getValue());
	}

	private static IDrawer getDrawer(JComponent comp) {
		try {
			Class<? extends JComponent> clazz = comp.getClass();
			Field field = clazz.getDeclaredField("drawer");
			field.setAccessible(true);
			MultiDrawer result = (MultiDrawer) field.get(comp);
			return result; 
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private DiagramData newDiagramData2() {
		DiagramData d = new DiagramData();
		d.x = new double[] { 1, 2 };
		d.y = new double[] { 10, 20 };
		return d;
	}

	private DiagramData newDiagramData3() {
		DiagramData d = new DiagramData();
		d.y = new double[] { 11, 12, 13 };
		d.x = new double[] { 110, 120, 130 };
		return d;
	}
}
